use clap::Parser;
use wtask_app::{AppTaskAdd, AppTaskDownload, TaskAddMeta, cli_app, msg_func_print};
use wtask_base::{error::WResult, export::{log_error, log_info, tokio_spawn}, logs::LogArgs, machine::{CMDArgsConfigAll, CMDArgsConfigMachine, WTASK_CLI_CONFIG_FILE, get_config, load_config_from_file, runtime_init}};



#[derive(Debug, Parser, Clone)]
pub struct CMDSubSync {
    #[command(flatten)]
    remote: CMDArgsConfigMachine,

    /// 使用指定配置文件
    #[arg(long)]
    config: Option<String>,

    #[command(flatten)]
    pub log_args: LogArgs,
}


impl CMDSubSync {
    pub fn run(self) -> WResult<()> {
        let config_remote = get_config(CMDArgsConfigAll::Machine(self.remote))?.pop().expect("No remote found");
        log_info!("Get remote: {config_remote:?}");
        let config_all = load_config_from_file(WTASK_CLI_CONFIG_FILE, None)?;
        log_info!("Get local: {config_all:?}");
        let runtime = runtime_init(4)?;
        runtime.block_on(async move {
            log_info!("Download task archv ...");
            let p: Option<String> = match cli_app(AppTaskDownload::default(), &config_remote, None, msg_func_print).await {
                Ok(Some(v)) => {
                    Some(v.into())
                },
                Err(e) => {
                    log_error!("Task Download Error: {e}");
                    None
                },
                v => {
                    log_error!("Task Download Error, res not matched: {:?}", v);
                    None
                }
            };
            
            if p.is_none() {
                return ;
            }
            let p = p.unwrap();
            log_info!("Get task archv: {p}");
            let hs = config_all.into_iter().map(| config | {
                let pp = p.clone();
                tokio_spawn(async move {
                    let machine_info = config.to_string();
                    let app_task_add = AppTaskAdd {
                        data: TaskAddMeta {
                            path: pp,
                            no_wait: false,
                            version: None
                        },
                        archv: true
                    };
                    log_info!("Install task for {machine_info} ...");
                    match cli_app(app_task_add, &config, None, msg_func_print).await {
                        Ok(_) => {
                            log_info!("Complete {machine_info} ");
                        },
                        Err(e) => {
                            log_error!("Error {machine_info} {e}");
                        }
                    };
                })
            }).collect::<Vec<_>>();
            for handle in hs {
                let _ = handle.await;
            }
        });
        runtime.shutdown_background();
        Ok(())
    }
}

